package com.wu.client.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wu.client.constant.RelationShipTypeEnum;


import com.wu.client.service.RelationshipService;
import com.wu.mysql.entiy.ArtistDO;
import com.wu.mysql.entiy.RelationshipDO;
import com.wu.mysql.mapper.ArtistMapper;
import com.wu.mysql.mapper.RelationshipMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class RelationshipServiceImpl extends ServiceImpl<RelationshipMapper, RelationshipDO> implements RelationshipService {
    private final ArtistMapper artistMapper;

    private void buildCommonWrapper(LambdaQueryWrapper<RelationshipDO> queryWrapper, RelationShipTypeEnum relationShipTypeEnum) {
        queryWrapper.eq(RelationshipDO::getRelationshipType, relationShipTypeEnum.getCode());
    }

    private <K> LambdaQueryWrapper<RelationshipDO> buildWrapperByField(RelationShipTypeEnum relationShipTypeEnum, K value, SFunction<RelationshipDO, Long> field) {
        LambdaQueryWrapper<RelationshipDO> queryWrapper = new LambdaQueryWrapper<>();
        buildCommonWrapper(queryWrapper, relationShipTypeEnum);

        if (value instanceof List) {
            queryWrapper.in(field, (List<?>) value);
        } else if (value != null) {
            queryWrapper.eq(field, value);
        }
        return queryWrapper;
    }

    @Override
    public Page<RelationshipDO> getPageInTargetIds(RelationShipTypeEnum relationShipTypeEnum, List<Long> targetIds, Integer page, Integer limit) {

        return this.getPage(relationShipTypeEnum, RelationshipDO::getTargetId, targetIds, page, limit);
    }

    @Override
    public Page<RelationshipDO> getPageInSourceIds(RelationShipTypeEnum relationShipTypeEnum, List<Long> sourceIds, Integer page, Integer limit) {
        return this.getPage(relationShipTypeEnum, RelationshipDO::getSourceId, sourceIds, page, limit);
    }

    @Override
    public Page<RelationshipDO> getPageByTargetId(RelationShipTypeEnum relationShipTypeEnum, Long targetId, Integer page, Integer limit) {
        return this.getPage(relationShipTypeEnum, RelationshipDO::getTargetId, targetId, page, limit);
    }

    @Override
    public Page<RelationshipDO> getPageBySourceId(RelationShipTypeEnum relationShipTypeEnum, Long sourceId, Integer page, Integer limit) {
        return this.getPage(relationShipTypeEnum, RelationshipDO::getSourceId, sourceId, page, limit);
    }

    @Override
    public List<RelationshipDO> getBySourceId(RelationShipTypeEnum relationShipTypeEnum, Long sourceId) {
        LambdaQueryWrapper<RelationshipDO> queryWrapper = buildWrapperByField(relationShipTypeEnum, sourceId, RelationshipDO::getSourceId);
        return this.list(queryWrapper);
    }

    @Override
    public List<RelationshipDO> getByTargetId(RelationShipTypeEnum relationShipTypeEnum, Long targetId) {
        LambdaQueryWrapper<RelationshipDO> queryWrapper = buildWrapperByField(relationShipTypeEnum, targetId, RelationshipDO::getTargetId);
        return this.list(queryWrapper);
    }

    @Override
    public List<RelationshipDO> getInSourceId(RelationShipTypeEnum relationShipTypeEnum, List<Long> sourceIds) {
        LambdaQueryWrapper<RelationshipDO> queryWrapper = buildWrapperByField(relationShipTypeEnum, sourceIds, RelationshipDO::getSourceId);
        return this.list(queryWrapper);
    }

    @Override
    public List<RelationshipDO> getInTargetId(RelationShipTypeEnum relationShipTypeEnum, List<Long> targetIds) {
        LambdaQueryWrapper<RelationshipDO> queryWrapper = buildWrapperByField(relationShipTypeEnum, targetIds, RelationshipDO::getTargetId);
        return this.list(queryWrapper);
    }

    @Override
    public String  getArtisName(Long resId, RelationShipTypeEnum relationShipTypeEnum) {
        List<RelationshipDO> relationshipDOS = getByTargetId(relationShipTypeEnum, resId);
        if (CollectionUtil.isNotEmpty(relationshipDOS)) {
            List<Long> artistIds = relationshipDOS.stream().map(RelationshipDO::getSourceId).collect(Collectors.toList());
            List<ArtistDO> artistDOS = artistMapper.selectBatchIds(artistIds);
            if (CollectionUtil.isNotEmpty(artistDOS)) {
                return artistDOS.stream().map(ArtistDO::getName).collect(Collectors.joining("/"));
            }
        }
        return "未知名歌手";
    }

    private <K> Page<RelationshipDO> getPage(RelationShipTypeEnum relationShipTypeEnum, SFunction<RelationshipDO, Long> field, K value, Integer page, Integer limit) {
        Page<RelationshipDO> doPage = new Page<>(page, limit);
        LambdaQueryWrapper<RelationshipDO> queryWrapper = buildWrapperByField(relationShipTypeEnum, value, field);
        return this.page(doPage, queryWrapper);
    }


}
